﻿//Copyright (c) 2013 Tilo Szepan, Immo Wache
//Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
//documentation files (the "Software"), to deal in the Software without restriction, including without limitation
//the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
//and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

//The above copyright notice and this permission notice shall be included in all copies or substantial portions 
//of the Software.

//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
//TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
//THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
//CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
//DEALINGS IN THE SOFTWARE.


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;
using System.Collections;
using System.IO;
using MonoMobile.Dialogs.Remote.Discovery;

namespace DuinoClient

{
    public class ServerSelect : Form
    {
        ListView listView;
        FormMain _main;
        UsidClient uclient;
        Button btn_apply, btn_reload;
        int tickCount;
        Timer timer;

        public ServerSelect(FormMain main)
        {
            _main = main;
            listView = new ListView();
            listView.Dock = DockStyle.Fill;
            listView.View = View.Details;
            listView.FullRowSelect = true;
            listView.Sorting = SortOrder.None;
            listView.MultiSelect = false;
            listView.Columns.Add("Name", 150, HorizontalAlignment.Left);
            listView.Columns.Add("IP Address", 150, HorizontalAlignment.Left);
            Controls.Add(listView);
            Controls.Add(Buttons());
            listView.SelectedIndexChanged += new EventHandler(listView_SelectedIndexChanged);
            listView.DoubleClick += new EventHandler(listView_DoubleClick);

            Size = new Size(350, 200);
            Text = "Server found:";
//            Show(main);

            uclient = new UsidClient();
            uclient.EnableBroadcast = true;
            uclient.DataReceived += DataReceived;
            uclient.Start();
            uclient.SendTo("255.255.255.255", 8221, new byte[] { 0 });
        }

        void listView_SelectedIndexChanged(object sender, EventArgs e)
        {
            btn_apply.Enabled = listView.SelectedIndices.Count == 1;
        }

        Control Buttons()
        {
            var btn_close = new Button();
            btn_close.Text = "Cancel";
            btn_close.AutoSize = true;
            btn_close.Dock = DockStyle.Right;
            btn_close.Click += delegate { Close(); };
            btn_apply = new Button();
            btn_apply.Text = "Apply";
            btn_apply.AutoSize = true;
            btn_apply.Dock = DockStyle.Right;
            btn_apply.Enabled = false;
            btn_apply.Click += listView_DoubleClick;

            btn_reload = new Button();
            btn_reload.Text = "reload";
            btn_reload.AutoSize = true;
            btn_reload.Dock = DockStyle.Left;
//            btn_load.Enabled = false;
            btn_reload.Click += new EventHandler(btn_reload_Click);
            
            var c = new Control();
            c.Controls.Add(btn_apply);
            c.Controls.Add(btn_close);
            c.Controls.Add(btn_reload);
            c.Dock = DockStyle.Bottom;
            c.Height = 30;
            c.IsAccessible = false;
            return c;
        }

        void btn_reload_Click(object sender, EventArgs e)
        {
            listView.Items.Clear();
            tickCount = 3;
            btn_reload.Enabled = false;
            timer = new Timer();
            timer.Interval = 1000;
            timer.Tick += new EventHandler(timer_Tick);
            timer_Tick(null, null);
            timer.Start();

//            uclient.SendTo("255.255.255.255", 8221, new byte[] { 0 });
        }

        void timer_Tick(object sender, EventArgs e)
        {
            uclient.SendTo("255.255.255.255", 8221, new byte[] { 0 });
            if (timer != null && --tickCount <= 0)
            {
                timer.Stop();
                timer.Dispose();
                timer = null;
                btn_reload.Enabled = true;
            }
        }

        void listView_DoubleClick(object sender, EventArgs e)
        {
            if (listView.SelectedItems.Count > 0)
            {
                var itm = listView.SelectedItems[0];
                _main.SetPath(itm.SubItems[1].Text);
                Close();
            }
        }
        public void DataReceived(object sender, DataReceivedEventArgs e)
        {
            var msg = (ResponseMessage)SerializerHelpers.Deserialize(e.Data, typeof(ResponseMessage));
//            Console.WriteLine(msg.Description + msg.IPAddress + msg.IPPort + msg.Prefix + e.RemoteEndPoint.ToString());
            string remaddr = "http://" + msg.IPAddress + (msg.IPPort != 80 ? ":" + msg.IPPort : null) + '/';
            if (InvokeRequired)
            {
//                Console.WriteLine("InvokeRequired");
                Action<string, string> d = AppendServer;
                Invoke(d, msg.Description, remaddr);
            }
            else
            {
                AppendServer(msg.Description, remaddr);
            }
        }
        void AppendServer(string s1, string s2)
        {
            foreach (ListViewItem item in listView.Items)
            {
                var subs = item.SubItems;
                if (subs[0].Text == s1 && subs[1].Text == s2)
//                    Console.WriteLine("AppendServer: false");
                    return;
            }
            var newItem = new ListViewItem(new[] { s1, s2 });
            listView.Items.Add(newItem);
            if (listView.SelectedIndices.Count == 0) newItem.Selected = true;
        }
        protected override void OnClosed(EventArgs e)
        {
            base.OnClosed(e);
            Finish();
        }
        void Finish() {
            uclient.Stop();
            if (timer != null)
            {
                timer.Stop();
                timer.Dispose();
                timer = null;
            }
            Dispose();
        }
    }

}
